import type { CollectionEntry } from "astro:content";
import { getCollection } from "astro:content";
import * as fs from "node:fs";
import type { APIContext, GetStaticPaths } from "astro";
import satori from "satori";
import sharp from "sharp";

import { profileConfig } from "../../config/profileConfig";
import { siteConfig } from "../../config/siteConfig";

type Weight = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;

type FontStyle = "normal" | "italic";
interface FontOptions {
  data: Buffer | ArrayBuffer;
  name: string;
  weight?: Weight;
  style?: FontStyle;
  lang?: string;
}
export const prerender = true;

export const getStaticPaths: GetStaticPaths = async () => {
  if (!siteConfig.generateOgImages) {
    return [];
  }

  const allPosts = await getCollection("posts");
  const publishedPosts = allPosts.filter((post) => !post.data.draft);

  return publishedPosts.map((post) => ({
    params: { slug: post.slug },
    props: { post },
  }));
};

async function fetchNotoSansSCFonts() {
  try {
    const cssResp = await fetch(
      "https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap"
    );
    if (!cssResp.ok) throw new Error("Failed to fetch Google Fonts CSS");
    const cssText = await cssResp.text();

    const getUrlForWeight = (weight: number) => {
      const blockRe = new RegExp(
        `@font-face\\s*{[^}]*font-weight:\\s*${weight}[^}]*}`,
        "g"
      );
      const match = cssText.match(blockRe);
      if (!match || match.length === 0) return null;
      const urlMatch = match[0].match(/url\((https:[^)]+)\)/);
      return urlMatch ? urlMatch[1] : null;
    };

    const regularUrl = getUrlForWeight(400);
    const boldUrl = getUrlForWeight(700);

    if (!regularUrl || !boldUrl) {
      console.warn(
        "Could not find font urls in Google Fonts CSS; falling back to no fonts."
      );
      return { regular: null, bold: null };
    }

    const [rResp, bResp] = await Promise.all([
      fetch(regularUrl),
      fetch(boldUrl),
    ]);
    if (!rResp.ok || !bResp.ok) {
      console.warn(
        "Failed to download font files from Google; falling back to no fonts."
      );
      return { regular: null, bold: null };
    }

    const rBuf = Buffer.from(await rResp.arrayBuffer());
    const bBuf = Buffer.from(await bResp.arrayBuffer());

    return { regular: rBuf, bold: bBuf };
  } catch (err) {
    console.warn("Error fetching fonts:", err);
    return { regular: null, bold: null };
  }
}

export async function GET({
  props,
}: APIContext<{ post: CollectionEntry<"posts"> }>) {
  const { post } = props;

  // Try to fetch fonts from Google Fonts (woff2) at runtime.
  const { regular: fontRegular, bold: fontBold } = await fetchNotoSansSCFonts();

  // Avatar + icon: still read from disk (small assets)
  let avatarBase64: string;

  // 检查头像是否为 URL
  if (profileConfig.avatar?.startsWith("http")) {
    // 如果是 URL，直接使用
    avatarBase64 = profileConfig.avatar;
  } else {
    // 如果是本地路径，从 public 目录读取
    const avatarPath = profileConfig.avatar?.startsWith("/")
      ? `./public${profileConfig.avatar}`
      : `./src/${profileConfig.avatar}`;
    const avatarBuffer = fs.readFileSync(avatarPath);
    avatarBase64 = `data:image/png;base64,${avatarBuffer.toString("base64")}`;
  }

  let iconPath = "./public/favicon/favicon-dark-192.png";
  if (siteConfig.favicon.length > 0) {
    iconPath = `./public${siteConfig.favicon[0].src}`;
  }
  const iconBuffer = fs.readFileSync(iconPath);
  const iconBase64 = `data:image/png;base64,${iconBuffer.toString("base64")}`;

  const hue = siteConfig.themeColor.hue;
  const primaryColor = `hsl(${hue}, 90%, 65%)`;
  const textColor = "hsl(0, 0%, 95%)";

  const subtleTextColor = `hsl(${hue}, 10%, 75%)`;
  const backgroundColor = `hsl(${hue}, 15%, 12%)`;

  const pubDate = post.data.published.toLocaleDateString("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
  });

  const description = post.data.description;

  const template = {
    type: "div",
    props: {
      style: {
        height: "100%",
        width: "100%",
        display: "flex",
        flexDirection: "column",
        backgroundColor: backgroundColor,
        fontFamily:
          '"Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
        padding: "60px",
      },
      children: [
        {
          type: "div",
          props: {
            style: {
              width: "100%",
              display: "flex",
              alignItems: "center",
              gap: "20px",
            },
            children: [
              {
                type: "img",
                props: {
                  src: iconBase64,
                  width: 48,
                  height: 48,
                  style: { borderRadius: "10px" },
                },
              },
              {
                type: "div",
                props: {
                  style: {
                    fontSize: "36px",
                    fontWeight: 600,
                    color: subtleTextColor,
                  },
                  children: siteConfig.title,
                },
              },
            ],
          },
        },

        {
          type: "div",
          props: {
            style: {
              display: "flex",
              flexDirection: "column",
              justifyContent: "center",
              flexGrow: 1,
              gap: "20px",
            },
            children: [
              {
                type: "div",
                props: {
                  style: {
                    display: "flex",
                    alignItems: "flex-start",
                  },
                  children: [
                    {
                      type: "div",
                      props: {
                        style: {
                          width: "10px",
                          height: "68px",
                          backgroundColor: primaryColor,
                          borderRadius: "6px",
                          marginTop: "14px",
                        },
                      },
                    },
                    {
                      type: "div",
                      props: {
                        style: {
                          fontSize: "72px",
                          fontWeight: 700,
                          lineHeight: 1.2,
                          color: textColor,
                          marginLeft: "25px",
                          display: "-webkit-box",
                          overflow: "hidden",
                          textOverflow: "ellipsis",
                          lineClamp: 3,
                          WebkitLineClamp: 3,
                          WebkitBoxOrient: "vertical",
                        },
                        children: post.data.title,
                      },
                    },
                  ],
                },
              },
              description && {
                type: "div",
                props: {
                  style: {
                    fontSize: "32px",
                    lineHeight: 1.5,
                    color: subtleTextColor,
                    paddingLeft: "35px",
                    display: "-webkit-box",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    lineClamp: 2,
                    WebkitLineClamp: 2,
                    WebkitBoxOrient: "vertical",
                  },
                  children: description,
                },
              },
            ],
          },
        },
        {
          type: "div",
          props: {
            style: {
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              width: "100%",
            },
            children: [
              {
                type: "div",
                props: {
                  style: {
                    display: "flex",
                    alignItems: "center",
                    gap: "20px",
                  },
                  children: [
                    {
                      type: "img",
                      props: {
                        src: avatarBase64,
                        width: 60,
                        height: 60,
                        style: { borderRadius: "50%" },
                      },
                    },
                    {
                      type: "div",
                      props: {
                        style: {
                          fontSize: "28px",
                          fontWeight: 600,
                          color: textColor,
                        },
                        children: profileConfig.name,
                      },
                    },
                  ],
                },
              },
              {
                type: "div",
                props: {
                  style: { fontSize: "28px", color: subtleTextColor },
                  children: pubDate,
                },
              },
            ],
          },
        },
      ],
    },
  };

  const fonts: FontOptions[] = [];
  if (fontRegular) {
    fonts.push({
      name: "Noto Sans SC",
      data: fontRegular,
      weight: 400,
      style: "normal",
    });
  }
  if (fontBold) {
    fonts.push({
      name: "Noto Sans SC",
      data: fontBold,
      weight: 700,
      style: "normal",
    });
  }

  const svg = await satori(template, {
    width: 1200,
    height: 630,
    fonts,
  });

  const png = await sharp(Buffer.from(svg)).png().toBuffer();

  return new Response(new Uint8Array(png), {
    headers: {
      "Content-Type": "image/png",
      "Cache-Control": "public, max-age=31536000, immutable",
    },
  });
}
